using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Web.UI;

namespace LightBox
{
    /// <summary>
    /// 
    /// </summary>
    /// <remarks>The following code was originally developed in VB.Net but then converted to C#.
    /// During the conversion process I found that aspitalia had also developed a similar control
    /// from which I learned a few new concepts, so they deserve credit too.
    /// You can find their article @ http://www.aspitalia.com/articoli/asp.net2/DataSource.aspx?page=2 </remarks>
    public class DirectoryDataSource : DataSourceControl
    {
        public string Directory
        {
            get { return (null == ViewState["Directory"] ? string.Empty : ViewState["Directory"].ToString()); }
            set { ViewState["Directory"] = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public virtual string FileMasks
        {
            get { return (null == ViewState["FileMasks"] ? "*.*" : ViewState["FileMasks"].ToString()); }
            set { ViewState["FileMasks"] = value; }
        }


        protected override System.Collections.ICollection GetViewNames()
        {
            return new string[] { "DefaultView" };
        }

        internal DirectoryDataSourceView _DirectoryDataSourceView;
        protected override DataSourceView GetView(string viewName)
        {
            if (null == _DirectoryDataSourceView)
            {
                _DirectoryDataSourceView = new DirectoryDataSourceView(this, String.Empty);
            }
            return new DirectoryDataSourceView(this, viewName);
        }
    }

    internal class DirectoryDataSourceView : DataSourceView
    {
        private DirectoryDataSource owner;

        public DirectoryDataSourceView(DirectoryDataSource owner, string viewName)
            : base(owner, viewName)
        {
            this.owner = owner;
        }

        public override bool CanDelete
        {
            get { return true; }
        }

        public override bool CanRetrieveTotalRowCount
        {
            get { return true; }
        }

        protected override System.Collections.IEnumerable ExecuteSelect(DataSourceSelectArguments arguments)
        {
            if (string.IsNullOrEmpty(this.owner.Directory))
                throw new InvalidOperationException("The Directory property is empty, you must specify a valid directory.");

            // Make sure that the directory that we are to list exists.
            DirectoryInfo directory = new DirectoryInfo(System.Web.HttpContext.Current.Server.MapPath(this.owner.Directory));
            if (!directory.Exists)
                throw new InvalidOperationException(String.Format("Directory {0} does not exist", directory.FullName));
            // TODO: Make sure that we have permissions to access the directory, use CAS as well.

            // Tell the caller that we know how many records we have.
            arguments.AddSupportedCapabilities(DataSourceCapabilities.RetrieveTotalRowCount);
            arguments.RaiseUnsupportedCapabilitiesError(this);

            // Break the filemasks into individual file mask patterns and create a 'super list' of all matching files.
            System.Collections.Generic.List<FileInfo> _files = new System.Collections.Generic.List<FileInfo>();
            string[] _FileMasks = this.owner.FileMasks.Split(";".ToCharArray());
            foreach (string IndividualMask in _FileMasks)
            {
                _files.AddRange(directory.GetFiles(IndividualMask));
            }

            arguments.TotalRowCount = _files.Count;

            return _files;
        }

        protected override int ExecuteDelete(System.Collections.IDictionary keys, System.Collections.IDictionary oldValues)
        {
            int deletedCount = 0;

            foreach (System.Collections.DictionaryEntry FileItem in keys)
            {
                string FilePath = FileItem.Key as string; // keys["FullName"];

                if (FilePath == null)
                    throw new InvalidOperationException("Delete parameters must include a full file path");

                File.Delete(FilePath);
                deletedCount++;
            }
            return deletedCount;
        }

        /// <summary>
        /// We don't really need to code this as the default action is for the base class to throw a NotSupportedException.
        /// This is here really as an example of where you can extend the class.
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        protected override int ExecuteInsert(System.Collections.IDictionary values)
        {
            throw new NotSupportedException();
        }

        protected override int ExecuteUpdate(System.Collections.IDictionary keys, System.Collections.IDictionary values, System.Collections.IDictionary oldValues)
        {
            throw new NotSupportedException();
        }
    }
}
